#include <arpa/inet.h>
#include <errno.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <pcap.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <uv.h>

#define MAXBUF 2048
#define DEFAULT_PORT 6666
#define DEFAULT_BACKLOG 128
#define MY_IP_ADDRESS "192.168.2.2"
void *clientPtr = NULL;
pcap_t *handle = NULL;
uv_loop_t *loop;
struct sockaddr_in addr;
uv_async_t async;
uint8_t mac[6] = "";

typedef struct {
  uv_write_t req;
  uv_buf_t buf;
} write_req_t;

void get_mac_address() {
  int fd;
  struct ifreq ifr;
  char *iface = "eth2";

  fd = socket(AF_INET, SOCK_DGRAM, 0);

  ifr.ifr_addr.sa_family = AF_INET;
  strncpy(ifr.ifr_name, iface, IFNAMSIZ - 1);

  if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
    perror("ioctl");
    exit(1);
  }

  memcpy(mac, ifr.ifr_ifru.ifru_addr.sa_data, 6);

  printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2],
         mac[3], mac[4], mac[5]);

  close(fd);
}

void free_write_req(uv_write_t *req) {
  write_req_t *wr = (write_req_t *)req;
  free(wr->buf.base);
  free(wr);
}

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
  buf->base = (char *)malloc(suggested_size);
  buf->len = suggested_size;
}

void on_close(uv_handle_t *handle) { free(handle); }

void echo_write(uv_write_t *req, int status) {
  if (status) {
    fprintf(stderr, "Write error %s\n", uv_strerror(status));
  }
  free_write_req(req);
}

void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
  printf("echo_read %d\n", nread);
  if (nread > 0) {
    for (int32_t i = 0; i < nread; i++) {
      printf("%02x ", *((uint8_t *)(buf->base) + i));
    }
    printf("\n");
    pcap_sendpacket(handle, (const u_char *)buf->base, nread);
    return;
  }
  if (nread < 0) {
    if (nread != UV_EOF)
      fprintf(stderr, "Read error %s\n", uv_err_name(nread));
    uv_close((uv_handle_t *)client, on_close);
  }

  free(buf->base);
}

void on_new_connection(uv_stream_t *server, int status) {
  if (status < 0) {
    fprintf(stderr, "New connection error %s\n", uv_strerror(status));
    // error!
    return;
  }
  printf("new connection\n");
  uv_tcp_t *client = (uv_tcp_t *)malloc(sizeof(uv_tcp_t));
  //   clientPtr = client;
  uv_tcp_init(loop, client);
  if (uv_accept(server, (uv_stream_t *)client) == 0) {
    uv_read_start((uv_stream_t *)client, alloc_buffer, echo_read);
  } else {
    uv_close((uv_handle_t *)client, on_close);
  }
}

void *pcap_recv_loop(void *arg) {
  pcap_t *handle = (pcap_t *)arg;
  struct pcap_pkthdr pkthdr;
  const uint8_t *packet;
  while (1) {
    packet = pcap_next(handle, &pkthdr);
    if (packet == NULL) {
      continue;
    }

    // Check if the packet is incoming or outgoing
    if (memcmp(packet + 6, mac, sizeof(mac)) == 0) {
      printf("Outgoing packet: %02x:%02x:%02x:%02x:%02x:%02x -> "
             "%02x:%02x:%02x:%02x:%02x:%02x\n",
             *(packet), *(packet + 1), *(packet + 2), *(packet + 3),
             *(packet + 4), *(packet + 5), mac[0], mac[1], mac[2], mac[3],
             mac[4], mac[5]);
      for (int i = 0; i < pkthdr.len; ++i) {
        printf("%02X ", packet[i]);
        if ((i + 1) % 16 == 0)
          printf("\n"); // 每行打印16个字节
      }
      printf("\n");

      write_req_t *req = (write_req_t *)malloc(sizeof(write_req_t));
      req->buf = uv_buf_init(packet, pkthdr.len);
      printf("send packet:\n");
      for (int i = 0; i < pkthdr.len; ++i) {
        printf("%02X ", packet[i]);
        if ((i + 1) % 16 == 0)
          printf("\n"); // 每行打印16个字节
      }

      async.data = (void *)req;
      uv_async_send(&async);
    } else if (memcmp(packet, mac, sizeof(mac)) == 0) {
      printf("InComing packet: %02x:%02x:%02x:%02x:%02x:%02x -> "
             "%02x:%02x:%02x:%02x:%02x:%02x\n",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], *(packet),
             *(packet + 1), *(packet + 2), *(packet + 3), *(packet + 4),
             *(packet + 5));
      for (int i = 0; i < pkthdr.len; ++i) {
        printf("%02X ", packet[i]);
        if ((i + 1) % 16 == 0)
          printf("\n"); // 每行打印16个字节
      }
      printf("\n");
    }
  }
}

void async_cb(uv_async_t *handle) {
  //   write_req_t *req = (write_req_t *)handle->data;
  //   uv_write((uv_write_t *)req, (uv_stream_t *)clientPtr, &req->buf, 1,
  //            echo_write);
}

int main() {
  char errbuff[PCAP_ERRBUF_SIZE];
  //    const char *dev = pcap_lookupdev(errbuff);
  struct sockaddr_in dest;
  const char *dev = "eth2";
  char buffer[MAXBUF];
  loop = uv_default_loop();

  uv_tcp_t server;
  uv_tcp_init(loop, &server);

  uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr);

  uv_tcp_bind(&server, (const struct sockaddr *)&addr, 0);
  get_mac_address();
  handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuff);
  if (handle == NULL) {
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuff);
    return 2;
  }

  pthread_t thread1;
  pthread_create(&thread1, NULL, pcap_recv_loop, handle);

  uv_async_init(loop, &async, async_cb);
  int r = uv_listen((uv_stream_t *)&server, DEFAULT_BACKLOG, on_new_connection);
  if (r) {
    fprintf(stderr, "Listen error %s\n", uv_strerror(r));
    return 1;
  }
  return uv_run(loop, UV_RUN_DEFAULT);
}
